﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Strategy.Core.Trade;

namespace Strategy.Core
{
    public abstract class AContext
    {
        protected abstract void initImplementation();
        public AContext(IStrategy s,ITrader itr)       
        { 
            Trader = itr;
            Strategy = s;
            initImplementation();
            if (statesTable != null && statesTable.Count != 0)
                CurrentState = statesTable.First().Value;

        }
        public IDataModel DataModel           { get; protected set; }
        private AState     CurrentState        { get; set; }

        public string CurrentStateName 
        {
            get
            {
                if (CurrentState == null)
                    if (statesTable.Count == 0)
                        return null;
                    else
                        CurrentState = statesTable.First().Value;
                return CurrentState.StateName;
            } 
        }
        protected IAction Action { get; set; }
        private Dictionary<string, AState> statesTable = new Dictionary<string, AState>();
        private Dictionary<string, AEvent> eventsTable = new Dictionary<string, AEvent>();
        protected IStrategy Strategy;
        protected ITrader Trader;

        public void DoAction()
        {
            Action.DoAction();
            CurrentState = CurrentState.DoTransition();
        }
        public void createState(string state)
        {
            if (!statesTable.ContainsKey(state))
                statesTable[state] = new AState(state);
        }
        public void createEvent(string eventname,
                                     string startstate,
                                     string endstate,
                                     ICondition condition,IAction action)
        {
            if (eventsTable.ContainsKey(eventname))
                throw new Exception();
            createState(startstate);
            createState(endstate);
            AEvent e = new AEvent(eventname, statesTable[startstate], statesTable[endstate],action);
            statesTable[startstate].AddEdge(condition, e);
        }
        public void removeState(string state)
        {
            if (!statesTable.ContainsKey(state))
                return;
            var col = statesTable[state];
            foreach (var el in col.GetOutEvents())
                removeEvent(el.Name);
            statesTable.Remove(state);

        }
        public void removeEvent(string eve)
        {
            eventsTable.Remove(eve);
        }
    }
}
